package io.gitee.zhangbinhub.admin.workflow.controller.api

import cn.dev33.satoken.annotation.SaCheckPermission
import io.gitee.zhangbinhub.acp.boot.exceptions.WebException
import io.gitee.zhangbinhub.acp.boot.log.LogAdapter
import io.gitee.zhangbinhub.admin.common.api.WorkFlowApi
import io.gitee.zhangbinhub.admin.common.constant.ModuleFuncCode
import io.gitee.zhangbinhub.admin.common.constant.RoleCode
import io.gitee.zhangbinhub.admin.common.vo.CustomerQueryPageVo
import io.gitee.zhangbinhub.admin.common.vo.InfoVo
import io.gitee.zhangbinhub.admin.resource.server.base.BaseResourceServerController
import io.gitee.zhangbinhub.admin.resource.server.vo.ProcessDefinitionVo
import io.gitee.zhangbinhub.admin.workflow.po.ProcessDefinitionPo
import io.gitee.zhangbinhub.admin.workflow.po.ProcessDefinitionQueryPo
import io.gitee.zhangbinhub.admin.workflow.service.WorkFlowDefinitionService
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.Parameter
import io.swagger.v3.oas.annotations.tags.Tag
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import jakarta.validation.Valid
import jakarta.validation.constraints.NotEmpty
import jakarta.validation.constraints.NotNull
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.*

@Validated
@RestController
@RequestMapping(WorkFlowApi.basePath)
@Tag(name = "工作流部署")
class WorkFlowDefinitionController @Autowired
constructor(
    logAdapter: LogAdapter,
    private val workFlowDefinitionService: WorkFlowDefinitionService
) : BaseResourceServerController(logAdapter) {

    @Operation(summary = "新建工作流信息")
    @SaCheckPermission(ModuleFuncCode.flowDefinition, orRole = [RoleCode.SUPER])
    @PutMapping(value = [WorkFlowApi.definition], produces = [MediaType.APPLICATION_JSON_VALUE])
    @Throws(WebException::class)
    fun create(@RequestBody @Valid processDefinitionPo: ProcessDefinitionPo): ResponseEntity<InfoVo> =
        workFlowDefinitionService.create(processDefinitionPo).let {
            ResponseEntity.ok(InfoVo(message = "创建成功"))
        }

    @Operation(summary = "删除指定的工作流信息")
    @SaCheckPermission(ModuleFuncCode.flowDefinition, orRole = [RoleCode.SUPER])
    @DeleteMapping(value = [WorkFlowApi.definition], produces = [MediaType.APPLICATION_JSON_VALUE])
    fun delete(
        @Parameter(description = "id列表", required = true)
        @NotEmpty(message = "id不能为空")
        @NotNull(message = "id不能为空")
        @RequestBody
        idList: MutableList<Long>
    ): ResponseEntity<InfoVo> = workFlowDefinitionService.delete(idList).let {
        ResponseEntity.ok(InfoVo(message = "删除成功"))
    }

    @Operation(summary = "更新指定的工作流信息")
    @SaCheckPermission(ModuleFuncCode.flowDefinition, orRole = [RoleCode.SUPER])
    @PatchMapping(value = [WorkFlowApi.definition], produces = [MediaType.APPLICATION_JSON_VALUE])
    @Throws(WebException::class)
    fun update(@RequestBody @Valid processDefinitionPo: ProcessDefinitionPo): ResponseEntity<InfoVo> {
        if (processDefinitionPo.id == null) {
            throw WebException("ID不能为空")
        }
        return workFlowDefinitionService.update(processDefinitionPo).let {
            ResponseEntity.ok(InfoVo(message = "更新成功"))
        }
    }

    @Operation(summary = "查询工作流信息列表")
    @SaCheckPermission(ModuleFuncCode.flowDefinition, orRole = [RoleCode.SUPER])
    @PostMapping(value = [WorkFlowApi.definition], produces = [MediaType.APPLICATION_JSON_VALUE])
    @Throws(WebException::class)
    fun query(@RequestBody @Valid processDefinitionQueryPo: ProcessDefinitionQueryPo): ResponseEntity<CustomerQueryPageVo<ProcessDefinitionVo>> =
        ResponseEntity.ok(workFlowDefinitionService.query(processDefinitionQueryPo))

    @Operation(summary = "发布工作流")
    @SaCheckPermission(ModuleFuncCode.flowDefinition, orRole = [RoleCode.SUPER])
    @PostMapping(value = [WorkFlowApi.definitionPublish + "/{id}"], produces = [MediaType.APPLICATION_JSON_VALUE])
    @Throws(WebException::class)
    fun publish(@PathVariable(name = "id") id: Long): ResponseEntity<InfoVo> =
        workFlowDefinitionService.publish(id).let {
            ResponseEntity.ok(InfoVo(message = "发布成功"))
        }

    @Operation(summary = "取消发布工作流")
    @SaCheckPermission(ModuleFuncCode.flowDefinition, orRole = [RoleCode.SUPER])
    @DeleteMapping(value = [WorkFlowApi.definitionPublish + "/{id}"], produces = [MediaType.APPLICATION_JSON_VALUE])
    @Throws(WebException::class)
    fun unPublish(@PathVariable(name = "id") id: Long): ResponseEntity<InfoVo> =
        workFlowDefinitionService.unPublish(id).let {
            ResponseEntity.ok(InfoVo(message = "取消发布成功"))
        }

    @Operation(summary = "激活工作流")
    @SaCheckPermission(ModuleFuncCode.flowDefinition, orRole = [RoleCode.SUPER])
    @PostMapping(value = [WorkFlowApi.definitionActive + "/{id}"], produces = [MediaType.APPLICATION_JSON_VALUE])
    @Throws(WebException::class)
    fun active(@PathVariable(name = "id") id: Long): ResponseEntity<InfoVo> = workFlowDefinitionService.active(id).let {
        ResponseEntity.ok(InfoVo(message = "激活成功"))
    }

    @Operation(summary = "挂起工作流")
    @SaCheckPermission(ModuleFuncCode.flowDefinition, orRole = [RoleCode.SUPER])
    @DeleteMapping(value = [WorkFlowApi.definitionActive + "/{id}"], produces = [MediaType.APPLICATION_JSON_VALUE])
    @Throws(WebException::class)
    fun unActive(@PathVariable(name = "id") id: Long): ResponseEntity<InfoVo> =
        workFlowDefinitionService.unActive(id).let {
            ResponseEntity.ok(InfoVo(message = "挂起成功"))
        }

    @Operation(summary = "流程定义文件导入")
    @PostMapping(value = [WorkFlowApi.definitionImport], produces = [MediaType.APPLICATION_JSON_VALUE])
    @Throws(WebException::class)
    fun import(@RequestBody processDefinitionPo: ProcessDefinitionPo): ResponseEntity<InfoVo> =
        workFlowDefinitionService.import(processDefinitionPo).let {
            ResponseEntity.ok(InfoVo(message = "导入成功"))
        }

    @Operation(summary = "流程定义文件导出")
    @GetMapping(value = [WorkFlowApi.definitionExport + "/{id}"], produces = [MediaType.APPLICATION_JSON_VALUE])
    @Throws(WebException::class)
    fun export(request: HttpServletRequest, response: HttpServletResponse, @PathVariable(name = "id") id: Long) {
        workFlowDefinitionService.export(request, response, id)
    }
}
